#pragma once
#include "utilities/utilities.h"
#include <Windows.h>

class UsrModeLock
{
private:
	CRITICAL_SECTION mSection;
	bool m_Destroyed;
public:
	UsrModeLock() : m_Destroyed(false) {
		InitializeCriticalSection(&mSection);
	}

	UsrModeLock(const int spinCount) {
		InitializeCriticalSectionAndSpinCount(&mSection,spinCount);
	}

	~UsrModeLock() {
		if (!m_Destroyed) 
			::DeleteCriticalSection(&mSection);
	}

	void lock() {
		assert(!m_Destroyed);
		::EnterCriticalSection(&mSection);
	}

	void unLock() {
		assert(!m_Destroyed);
		::LeaveCriticalSection(&mSection);
	}
	
	bool tryLock() {
		assert(!m_Destroyed);
		return ::TryEnterCriticalSection(&mSection) ? true : false;
	}

	void destroy() {
		if (!m_Destroyed)
		{	
			::DeleteCriticalSection(&mSection);
			m_Destroyed = true;
		}
	}
};

class UsrModeLockLocker {
public:
	UsrModeLockLocker(UsrModeLock& usrlock) : m_Lock(usrlock) {m_Lock.lock();}
	UsrModeLockLocker(UsrModeLock* plock) : m_Lock(*plock) {m_Lock.lock();}
	~UsrModeLockLocker() {m_Lock.unLock();}

private:
	const UsrModeLockLocker& operator = (const UsrModeLockLocker&);
	UsrModeLockLocker(const UsrModeLockLocker&);

	UsrModeLock& m_Lock;
};